package cn.aiyuan;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedQueue<T> {

    private final LinkedList<T> buffer;    //生产者容器
    private final int maxSize;           //容器最大值是多少
    private final Lock lock;
    private final Condition fullCondition;
    private final Condition notFullCondition;

    BoundedQueue(int maxSize) {
        this.maxSize = maxSize;
        buffer = new LinkedList<T>();
        lock = new ReentrantLock();
        fullCondition = lock.newCondition();
        notFullCondition = lock.newCondition();
    }

    /**
     * 生产者
     *
     */
    public void put(T obj) throws InterruptedException {
        lock.lock();    //获取锁
        try {
            while (maxSize == buffer.size()) {
                notFullCondition.await();       //满了，添加的线程进入等待状态
            }
            buffer.add(obj);
            fullCondition.signal(); //通知
        } finally {
            lock.unlock();
        }
    }

    /**
     * 消费者
     */
    public T get() throws InterruptedException {
        T obj;
        lock.lock();
        try {
            while (buffer.size() == 0) { //队列中没有数据了 线程进入等待状态
                fullCondition.await();
            }
            obj = buffer.poll();
            notFullCondition.signal(); //通知
        } finally {
            lock.unlock();
        }
        return obj;
    }


    public static void main(String[] args) throws InterruptedException {
        BoundedQueue<Integer> boundedQueue = new BoundedQueue<Integer>(5);
        boundedQueue.put(1);
        boundedQueue.put(1);
        boundedQueue.put(1);
        boundedQueue.put(1);
        boundedQueue.put(1);
        System.out.println(boundedQueue.get());
    }
}
